﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MindFusion.Diagramming;

namespace Inference
{
	public partial class frmEditStringParameter : Form
	{
		public string Value
		{
			get
			{
				return txbValue.Text;
			}
			set
			{
				txbValue.Text = value;
			}
		}

		TaleEntities tale = null;
		frmMain parentForm = null;
		TreeNode tn = null;
		RenamingType rt;
		string initString = "";

		public frmEditStringParameter()
		{
			InitializeComponent();
		}
		public frmEditStringParameter(string initString, string header, frmMain parentForm, TreeNode tn, RenamingType rt)
		{
			InitializeComponent();
			this.Text = header;
			this.parentForm = parentForm;
			txbValue.Text = initString;
			this.tn = tn;
			tale = new TaleEntities();
			this.rt = rt;
			this.initString = initString;
		}

        public frmEditStringParameter(string initString, string header, frmMain parentForm, RenamingType rt)
        {
            InitializeComponent();
            this.Text = header;
            this.parentForm = parentForm;
            txbValue.Text = initString;            
            tale = new TaleEntities();
            this.rt = rt;
            this.initString = initString;
        }

        private Frame getFrameByName_tolower(string name, TaleEntities tale)
        {
            var fr = tale.Frame.Where(f => f.Name.Trim().ToLower() == name.Trim().ToLower());
            if (fr.Count() > 0)
                return fr.First();
            return null;
        }

		private void frmEditStringParameter_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (DialogResult == DialogResult.OK)
			{
				RenamingResult res = RenamingResult.OK;
				if (Value.Trim() == "")
					res = RenamingResult.EmptyNameError;
				else
					switch (rt)
					{
						case RenamingType.Frame:
							if (parentForm.FrameExists(Value, tn))
								res = RenamingResult.FrameNameAlreadyExistsError;
							else
							{
								Frame rf = parentForm.getFrameByName(tn.Text, tale);
								if (rf != null)
								{
									var r = from d in tale.Domains
											join dv in tale.DomainsValues on d.ID equals dv.DomID
											join ddvv in tale.DValues on dv.Value equals ddvv.ID
											where d.Name == parentForm.sysDomEntities || d.Name == parentForm.sysDomSituations
											select ddvv;
									rf.Name = Value;
									r.First().Value = Value;
									tale.SaveChanges();
									parentForm.refreshFrameNodes(rf, initString);
								}
							}
							break;
                        case RenamingType.FrameFromEdit:
                            if (getFrameByName_tolower(txbValue.Text.Trim(), tale)!=null)
                                res = RenamingResult.FrameNameAlreadyExistsError;
                            else
                            {
                                Frame rf = parentForm.getFrameByName(tn.Text, tale);
                                if (rf != null)
                                {
                                    var r = from d in tale.Domains
                                            join dv in tale.DomainsValues on d.ID equals dv.DomID
                                            join ddvv in tale.DValues on dv.Value equals ddvv.ID
                                            where d.Name == parentForm.sysDomEntities || d.Name == parentForm.sysDomSituations
                                            select ddvv;
                                    rf.Name = Value;
                                    r.First().Value = Value;
                                    tale.SaveChanges();
                                    parentForm.refreshFrameNodes(rf, initString);
                                }
                            }
                            break;
                        case RenamingType.NewFrame:
                            Frame fr = getFrameByName_tolower(txbValue.Text.Trim(), tale);
                            if (fr != null)
                                res = RenamingResult.FrameNameAlreadyExistsError;
                            break;

						case RenamingType.Slot:
							if (CheckIf.SlotIsInherited(tn.Text, tn.Parent.Text))
								res = RenamingResult.SlotIsInherited;
							else
								if (!CheckIf.SlotNameIsUnique(Value, tn.Parent.Text, true, tale))
									res = RenamingResult.SlotNameAlreadyExistsInThisFrameError;
								else
								{
									foreach (Slot s in CheckIf.SlotsNamedLike(tn.Text, tn.Parent.Text, tale))
									{
										s.Name = Value;
										parentForm.RefreshSlotNodes(s, initString);
									}
									tale.SaveChanges();

								}
							break;
						case RenamingType.Domain:
							if (parentForm.DomainExists(Value, tn))
								res = RenamingResult.DomainNameAlreadyExistsError;
							else
							{
								Domains rd = parentForm.getDomainByName(tn.Text, tale);
								if (rd != null)
								{
									rd.Name = Value;
									tale.SaveChanges();
									parentForm.RefreshDomainNodes(rd, initString);
								}
							}
							break;
						case RenamingType.DomainValue:
							if (parentForm.DomainValueExists(Value, tn))
								res = RenamingResult.DomainValueAlreadyExistsInThisFrameError;
							else
							{
								DValues rdv = parentForm.getDomainValueByName(tn.Text, tn.Parent.Text, tale);
								if (rdv != null)
								{
									rdv.Value = Value;
									tale.SaveChanges();
									tn.Text = Value;
								}
							}
							break;
						case RenamingType.NewDomain:
							if (parentForm.DomainExists(Value, tn))
								res = RenamingResult.DomainNameAlreadyExistsError;
							else
							{
								DialogResult crt = (MessageBox.Show("Вы хотите создать корневой домен?\n(Да - корневой домен, Нет - поддомен)","Способ создания домена",MessageBoxButtons.YesNo,MessageBoxIcon.Question));

								if (crt == System.Windows.Forms.DialogResult.Yes)
								{

									frmEditStringParameter f = new frmEditStringParameter(
									"",
									"Добавление первого значения в домен '" + Value + "'.",
									parentForm,
									null, RenamingType.FirstDomainValue);
									if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
									{
										Domains d = new Domains();
										d.Name = Value;
										d.DomainsValues = new System.Data.Objects.DataClasses.EntityCollection<DomainsValues>();
										DomainsValues domval = new DomainsValues();
										domval.DValues = new DValues();
										domval.DValues.Value = f.Value;
										d.DomainsValues.Add(domval);
										tale.AddToDomains(d);
										tale.SaveChanges();
									}
								}else
									if (crt == System.Windows.Forms.DialogResult.No)
									{
										DomainBuilder f = null;
										if (tn.Tag.ToString() == "d")
										{
											f = new DomainBuilder(parentForm, tn.Text, parentForm.settings.FindLeaves(tn), null);
										}
										else
											if (tn.Tag.ToString() == "v")
											{
												f = new DomainBuilder(parentForm, tn.Parent.Text, parentForm.settings.FindLeaves(tn), null);
											}
										if (f == null)
										{
											f = new DomainBuilder(parentForm, null, new List<TreeNode>(), null);
										}
											if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
											{
												Domains d = new Domains();
												d.Name = Value;
												d.DomainsValues = new System.Data.Objects.DataClasses.EntityCollection<DomainsValues>();
												foreach (string item in f.ChosenValuesNames)
												{
													DomainsValues domval = new DomainsValues();
													DValues dv = tale.DValues.Where(q => q.Value == item).First();
													domval.DValues = dv;
													d.DomainsValues.Add(domval);
												}
												tale.AddToDomains(d);
												tale.SaveChanges();
											}
									}
							}
							break;
						case RenamingType.NewDomainValue:
							if (parentForm.DomainValueExists(Value, tn))
								res = RenamingResult.DomainValueAlreadyExistsInThisFrameError;
							else
							{
								Domains d = parentForm.getDomainByName(tn.Text, tale);
								DomainsValues domval = new DomainsValues();
								Domains baseDom = DomainHierarchier.GetParent(d.Name, tale);

								bool done = false;

								if (baseDom != null)
								{
									var dvv = DomainHierarchier.getDValues(baseDom.ID, tale);
									foreach (var item in dvv)
									{
										if (item.Value == Value)
										{
											domval.DValues = item;
											done = true;
											break;
										}
									}
								}
								if (!done)
								{
									domval.DValues = new DValues();
									domval.DValues.Value = Value;
								}
								
								d.DomainsValues.Add(domval);
								tale.SaveChanges();
								if(baseDom!= null)
									parentForm.SynchronizeDomains(d.Name, baseDom.Name);
							}
							break;
						default:
							break;
					}

				switch (res)
				{
					case RenamingResult.FrameNameAlreadyExistsError:
						lblError.Text = "Фрейм с таким именем уже есть";
						e.Cancel = true;
						break;
					case RenamingResult.SlotNameAlreadyExistsInThisFrameError:
						lblError.Text = "Слот с таким именем уже есть";
						e.Cancel = true;
						break;
					case RenamingResult.DomainNameAlreadyExistsError:
						lblError.Text = "Домен с таким именем уже есть";
						e.Cancel = true;
						break;
					case RenamingResult.DomainValueAlreadyExistsInThisFrameError:
						lblError.Text = "Такое значение в этом домене уже есть";
						e.Cancel = true;
						break;
					case RenamingResult.EmptyNameError:
						lblError.Text = "Имя не может быть пустым";
						e.Cancel = true;
						break;
					case RenamingResult.SlotIsInherited:
						lblError.Text = "Данный слот пронаследован";
						e.Cancel = true;
						break;
				}
			}
		}

        private void frmEditStringParameter_Load(object sender, EventArgs e)
        {
            txbValue.Select();
            txbValue.Focus();
        }
	}
}
